#include "test_bit_win_xml.h"


using namespace BitWin;


void TestBitWinXml::testRowTitles_data()
{
    QTest::addColumn<QDomElement>("xml_data");
    QTest::addColumn<QStringList>("titles_expected");
    
        QTest::newRow("empty (at all)")
        << createDoc("<empty_at_all/>") << QStringList()
    ;
    QTest::newRow("empty (no rows section)")
        << createDoc(
            "<empty>"
                "<Foo>"
                    "<Bar/>"
                "</Foo>"
                "<Baz/>"
            "</empty>"
        )
        << QStringList()
    ;
    QTest::newRow("empty rows")
        << createDoc(
            "<empty3>"
                "<rows/>"
            "</empty3>"
        )
        << QStringList()
    ;
    QTest::newRow("single word row")
        << createDoc(
            "<single>"
                "<rows>"
                    "<word title='Word z'/>"
                "</rows>"
            "</single>"
        )
        << (QStringList() << "Word z")
    ;
    QTest::newRow("dual word rows")
        << createDoc(
            "<dual>"
                "<rows>"
                    "<word title='Word x'/>"
                    "<word title='Word y'/>"
                "</rows>"
            "</dual>"
        )
        << (QStringList() << "Word x" << "Word y")
    ;
    QTest::newRow("words and fields")
        << createDoc(
            "<words_and_fields>"
                "<rows>"
                    "<word title='Word x'>"
                        "<field title='Field xx' bits='7:5'/>"
                        "<field title='Field xy' bits='5:0'/>"
                    "</word>"
                    "<word title='Word y'>"
                        "<field title='Field yx' bits='7:0'/>"
                    "</word>"
                    "<word title='Word z'/>"
                "</rows>"
            "</words_and_fields>"
        )
        << (QStringList()
            << "Word x" << "Field xx" << "Field xy"
            << "Word y" << "Field yx"
            << "Word z"
        )
    ;
    QTest::newRow("dual rows section")
        << createDoc(
            "<dual_rows_section>"
                "<rows>"
                    "<word title='Foo'/>"
                    "<word title='Bar'/>"
                "</rows>"
                "<rows>"
                    "<word title='Baz'/>"
                "</rows>"
            "</dual_rows_section>"
        )
        << (QStringList() << "Foo" << "Bar" << "Baz")
    ;
    QTest::newRow("nonsence tag")
        << createDoc(
            "<nonsence_tag>"
                "<rows>"
                    "<word title='Foo'/>"
                    "<Bark>"
                        "<word title='Bug'>"
                            "<field title='Buggy'/>"
                        "</word>"
                    "</Bark>"
                    "<word title='Bar'>"
                        "<field title='Baz'/>"
                    "</word>"
                "</rows>"
            "</nonsence_tag>"
        )
        << (QStringList() << "Foo" << "Bar" << "Baz")
    ;
    QTest::newRow("nonsence tag in word")
        << createDoc(
            "<nonsence_tag_in_word>"
                "<rows>"
                    "<word title='Foo'>"
                        "<field title='Bar'/>"
                        "<Bug/>"
                        "<field title='Baz'/>"
                    "</word>"
                "</rows>"
            "</nonsence_tag_in_word>"
        )
        << (QStringList() << "Foo" << "Bar" << "Baz")
    ;
    QTest::newRow("field tag not in place")
        << createDoc(
            "<field_not_in_place>"
                "<rows>"
                    "<word title='Foo'/>"
                    "<field title='Nonsense' bits='7:0'/>"
                    "<word title='Bar'/>"
                "</rows>"
            "</field_not_in_place>"
        )
        << (QStringList() << "Foo" << "Bar")
    ;
}

void TestBitWinXml::testRowTitles()
{
    QFETCH(QDomElement, xml_data);
    QVERIFY(!xml_data.isNull());
    QFETCH(QStringList, titles_expected);
    
    PRowList rows = FromXml::makeRows(xml_data);
    
    VERIFY_TITLES(rows, titles_expected);
}

void TestBitWinXml::testRowBehaviour_data()
{
    QTest::addColumn<QDomElement>("xml_data");
    QTest::addColumn<int>("role");
    QTest::addColumn<BitRange>("range");
    QTest::addColumn<PGenericBitwise>("indata");
    QTest::addColumn<QStringList>("outdata_expected");
    
    QTest::newRow("empty")
        << createDoc("<empty/>")
        << BITWISE_DATA_ROLE << BitRange(5, 0)
        << STRING_BITWISE("foo")
        << QStringList()
    ;
    QTest::newRow("single word")
        << createDoc(
            "<single_word>"
                "<rows>"
                    "<word title='Foo'/>"
                "</rows>"
            "</single_word>"
        )
        << BITWISE_DATA_ROLE << BitRange(5, 0)
        << STRING_BITWISE("bar")
        << (QStringList() << "bar   ")
    ;
    QTest::newRow("dual words")
        << createDoc(
            "<dual_words>"
                "<rows>"
                    "<word title='Foo'/>"
                    "<word title='Bar'/>"
                "</rows>"
            "</dual_words>"
        )
        << BITWISE_DATA_ROLE << BitRange(5,0)
        << STRING_BITWISE("bar")
        << (QStringList() << "bar   " << "bar   ")
    ;
    QTest::newRow("words and fields")
        << createDoc(
            "<words_and_fields>"
                "<rows>"
                    "<word title='Foo'>"
                        "<field title='Foo-1' bits='3:1'/>"
                        "<field title='Foo-2' bits='4:2'/>"
                        "<field title='Foo-3'/>"
                    "</word>"
                    "<word title='Bar'/>"
                "</rows>"
            "</words_and_fields>"
        )
        << BITWISE_DATA_ROLE << BitRange(5,0)
        << STRING_BITWISE("foo-bar-baz")
        << (QStringList()
            <<     "foo-ba"
                << " oo-  "
                << "  o-b "
                << "      "
            << "foo-ba"
        )
    ;
    QTest::newRow("words and fields, hex data role")
        << createDoc(
            "<words_and_fields>"
                "<rows>"
                    "<word title='Foo'>"
                        "<field title='Bar' bits='3:1'/>"
                    "</word>"
                    "<word title='Baz'/>"
                "</rows>"
            "</words_and_fields>"
        )
        << HEX_DATA_ROLE << BitRange(5,0)
        << GenericBitwise::fromIntegral<quint8>(0xCA)
        << (QStringList()
            << "0xca"
                << QString()
            << "0xca"
        )
    ;
}

void TestBitWinXml::testRowBehaviour()
{
    QFETCH(QDomElement, xml_data);
    QVERIFY(!xml_data.isNull());
    
    PRowList rows = FromXml::makeRows(xml_data);
    
    QFETCH(int, role);
    QFETCH(BitRange, range);
    QFETCH(PGenericBitwise, indata);
    QFETCH(QStringList, outdata_expected);
    
    QCOMPARE(rows.size(), outdata_expected.size());
    
    for (int i = 0; i < rows.size(); ++i)
        VERIFY_QVARIANT_QSTRING(
            rows[i]->data(role, range, indata),
            outdata_expected[i]
        );
}
